#ifndef FILE_H
#define FILE_H

#include "common.h"
#include "header.h"
#include "stackup_material.h"
#include "x01.h"
#include "x03.h"
#include "x04.h"
#include "x05.h"
#include "x06.h"
#include "x07.h"
#include "x08.h"
#include "x09.h"
#include "x0a.h"
#include "x0c.h"
#include "x0d.h"
#include "x0e.h"
#include "x0f.h"
#include "x10.h"
#include "x11.h"
#include "x12.h"
#include "x14.h"
#include "x15.h"
#include "x16.h"
#include "x17.h"
#include "x1b.h"
#include "x1c.h"
#include "x1d.h"
#include "x1e.h"
#include "x1f.h"
#include "x20.h"
#include "x22.h"
#include "x23.h"
#include "x24.h"
#include "x26.h"
#include "x27.h"
#include "x28.h"
#include "x2a.h"
#include "x2b.h"
#include "x2c.h"
#include "x2d.h"
#include "x2e.h"
#include "x30.h"
#include "x31.h"
#include "x32.h"
#include "x33.h"
#include "x34.h"
#include "x36.h"
#include "x37.h"
#include "x38.h"
#include "x39.h"
#include "x3a.h"
#include "x3b.h"
#include "x3c.h"

#include <optional>
#include <string>
#include <vector>
#include <map>

template <AllegroVersion version>
class File
{
public:
    header *hdr;
    std::vector<std::tuple<uint32_t, uint32_t>> layers;
    
    std::map<uint32_t, std::string> strings;
    std::map<uint32_t, x01<version>> x01_map;
    std::map<uint32_t, x03> x03_map;
    std::map<uint32_t, x04<version>> x04_map;
    std::map<uint32_t, x05<version>> x05_map;
    std::map<uint32_t, x06<version>> x06_map;
    std::map<uint32_t, x07<version>> x07_map;
    std::map<uint32_t, x08<version>> x08_map;
    std::map<uint32_t, x09<version>> x09_map;
    std::map<uint32_t, x0A<version>> x0A_map;
    std::map<uint32_t, x0C<version>> x0C_map;
    std::map<uint32_t, x0D<version>> x0D_map;
    std::map<uint32_t, x0E<version>> x0E_map;
    std::map<uint32_t, x0F<version>> x0F_map;
    std::map<uint32_t, x10<version>> x10_map;
    std::map<uint32_t, x11<version>> x11_map;
    std::map<uint32_t, x12> x12_map;
    std::map<uint32_t, x14<version>> x14_map;
    std::map<uint32_t, x15<version>> x15_map;
    std::map<uint32_t, x16<version>> x16_map;
    std::map<uint32_t, x17<version>> x17_map;
    std::map<uint32_t, x1B<version>> x1B_map;
    std::map<uint32_t, x1C<version>> x1C_map;
    std::map<uint32_t, x1D<version>> x1D_map;
    std::map<uint32_t, x1E> x1E_map;
    std::map<uint32_t, x1F<version>> x1F_map;
    std::map<uint32_t, x20<version>> x20_map;
    std::map<uint32_t, x22<version>> x22_map;
    std::map<uint32_t, x23<version>> x23_map;
    std::map<uint32_t, x24<version>> x24_map;
    std::map<uint32_t, x26<version>> x26_map;
    x27 x27_db;
    std::map<uint32_t, x28<version>> x28_map;
    std::map<uint32_t, x2A> x2A_map;
    std::map<uint32_t, x2B<version>> x2B_map;
    std::map<uint32_t, x2C<version>> x2C_map;
    std::map<uint32_t, x2D<version>> x2D_map;
    std::map<uint32_t, x2E<version>> x2E_map;
    std::map<uint32_t, x30<version>> x30_map;
    std::map<uint32_t, x31> x31_map;
    std::map<uint32_t, x32<version>> x32_map;
    std::map<uint32_t, x33<version>> x33_map;
    std::map<uint32_t, x34<version>> x34_map;
    std::map<uint32_t, x36<version>> x36_map;
    std::map<uint32_t, x37<version>> x37_map;
    std::map<uint32_t, x38<version>> x38_map;
    std::map<uint32_t, x39<version>> x39_map;
    std::map<uint32_t, x3A<version>> x3A_map;
    std::map<uint32_t, x3B<version>> x3B_map;
    std::map<uint32_t, x3C<version>> x3C_map;
    
    std::map<uint32_t, stackup_material> stackup_materials;
    std::optional<meta_netlist_path> netlist_path;
    
    uint8_t layer_count = 0;
    uint32_t x27_end_pos;
    
    operator File<A_174>() const;
};

#endif // FILE_H
